#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <assert.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/dir.h>
#include <sys/stat.h>

#include "bstrlib.h"
#include "server.h"
#include "fd_list.h"
#include "common.h"


int send_msg(int fd_client, char *msg){
    /*Esta funcion la utilizamos para las respuestas desde al cliente*/
    int aux_send = 0, length = 0, i=0, finished=0;
    char *aux_msg = NULL;
    assert (msg != NULL);
    assert (fd_client != 0);

    length = strlen(msg);

    while(finished == 0){
        #ifdef __DEBUG__
        printf("send_msg %s\n", msg);
        #endif
        aux_send = send(fd_client, msg, length, 0);
        if (aux_send == -1){
            perror("send");
            if (errno==ECONNRESET || errno==EPIPE || errno==ESPIPE){
                return -1;
            }
            return 0;
        }
        if (aux_send == length){
                finished = 1;
        }
        else{
            aux_msg = calloc(length,sizeof(char*));
            for (i=aux_send; i<length; i++){
                aux_msg[i-aux_send]=msg[i];
            }
            strncpy(msg, aux_msg, aux_send);
            length = strlen(msg);
            free(aux_msg);
            aux_msg = NULL;
        }
    }
    return 0;
}

void
get_response(fd_list list, int i){
    int aux_recv=0, fd_client=0;
    char *aux_buf=NULL;
    bstring received=NULL;
    /*Acá vamos a recibir y cargar en la estructura*/

    fd_client = fd_list_get_fd(list, i);

    aux_buf = calloc(BUF_LENGTH, sizeof(char*));
    if(aux_buf == NULL){
        perror("get_response_aux_buf_calloc");
        send_msg(fd_client, MSG199);
        close(fd_client);
        fd_list_remove(list, i);
        return;
    }
    aux_recv = recv(fd_client, aux_buf, BUF_LENGTH, 0);
    if (aux_recv == -1){
        perror("get_response_recv");
    }
    if (aux_recv == 0){
        #ifdef __DEBUG__
            printf("Se me ha desconectado el fd %i", fd_client);
        #endif
        free(aux_buf);
        aux_buf=NULL;
        fd_list_remove(list, i);
        return;
    }
    received = fd_list_get_data(list, i);
    /*concateno al bstring lo que recibi del server*/
    bcatblk(received, aux_buf, aux_recv);
    /*Ahora en received tengo lo que tenia más lo que recibi ahora
      y lo vuelvo a cargar en la estructura*/
    fd_list_clear_data(list, i);
    fd_list_set_data(list, i, received);
    return;
}
 
void
analize_response(fd_list list, int i){
    int sep_index=0, j=0, num=0;
    char *number=NULL, *end_ptr=NULL, *file_temp=NULL;
    bstring received=NULL, received_aux=NULL, sep=NULL;

    /*Acá vamos a analizar la primer linea de respuesta
      para saber si nos han respondido con algun error*/


    received = fd_list_get_data(list, i);
    /*indico el separador*/
    sep = blk2bstr("\r\n", 2);
    
    sep_index = binstr(received,0,sep);
    /*Ahora en sep_index tengo la ubicacion del \r\n
      En caso de que sea -1, es porque no obtuve el \r\n
      por ende marco como error y salgo*/
    if(sep_index == -1){
        fd_list_set_answ(list, i, -1);
        return;
    }
    
    /* En caso contrario, cargo en file_temp lo que tengo y
       analizo hasta encontrar un espacio para ver el codigo de respuesta*/
    file_temp=bstr2cstr(received,'\0');
    number = calloc(strlen(file_temp), sizeof(char));
    if(number==NULL){
        perror("get_response_number_calloc");
        return;
    }
    
    while (file_temp[j]!=' ' && j<sep_index){
        number[j] = file_temp[j];
        j++;
    }
    
    num = strtol(number, &end_ptr, 10);
    if (end_ptr != number){
        num = (int)num;
        free(number);
        number=NULL;
    }
    else{
        /*Si entra aca es porque el mensaje no viene correctamente
          (ie no viene un numero como codigo de respuesta*/
        printf("El primer elemento recibido no es entero\n");
        free(number);
        number=NULL;
        bcstrfree(file_temp);
        file_temp = NULL;
        return;
    }
    
    /*Cargo la respuesta en la estructura*/
    fd_list_set_answ(list, i, num);
    bdestroy(sep);
    received_aux = bstrcpy(received);
    bdestroy(received);
    /*Cargo en received desde la segunda linea en adelante*/
    received = bmidstr (received_aux, sep_index, blength(received_aux));
    /*Borro lo que habia en la estructura y cargo el nuevo dato*/
    fd_list_clear_data(list, i);
    fd_list_set_data(list, i, received);
    /*destruyo y salgo*/
    bdestroy(received);
    bdestroy(received_aux);
    
    bcstrfree(file_temp);
    return;
     
}

char *cargar(void){
  char *p;
  char c;/*=NULL;*/
  int i=1;

  p=(char*)malloc(sizeof(char));
  scanf("%c",&c);
  while (c=='\n')
    {
      scanf("%c",&c);
    }
  *p=c;
  i++;

  while(c!='\n')
    {
      p=(char*)realloc(p,sizeof(char)*i);
      scanf("%c",&c);
      p[i-1]=c;
      i++;
    }
  /*  p=(char*)realloc(p,sizeof(char)*i);*/
  p[i-2]='\0';
    
  return p;
    
}
